﻿using System;
using System.Linq;
using Godot;

namespace kemocard.Components.Pagination;

public partial class PaginationComponent : HBoxContainer
{
    [Export] public int ItemsPerPage { get; set; } = 10;

    private int _totalItems;
    private int _currentPage = 1;
    private int _totalPages;

    [Export] private Button _prevButton;
    [Export] private Button _nextButton;
    [Export] private Button _firstPageButton;
    [Export] private Button _lastPageButton;
    [Export] private LineEdit _pageInput;
    [Export] private Label _pageInfoLabel;
    [Export] private Button _goToButton;

    public Action<int> OnPageChanged;

    public void SetupUI()
    {
        // 创建首页按钮
        _firstPageButton.Text = "<<";
        _firstPageButton.Pressed += OnFirstPageButtonOnPressed;

        // 创建上一页按钮
        _prevButton.Text = "<";
        _prevButton.Pressed += GoToPreviousPage;

        // 创建页码信息标签
        _pageInfoLabel.Text = "Page 1 of 1";

        // 创建下一页按钮
        _nextButton.Text = ">";
        _nextButton.Pressed += GoToNextPage;

        // 创建末页按钮
        _lastPageButton.Text = ">>";
        _lastPageButton.Pressed += GoToLastPage;

        // 创建跳转到页码输入框
        _pageInput.CustomMinimumSize = new Vector2(50, 0);
        _pageInput.Text = "1";
        _pageInput.TextChanged += OnPageInputTextChanged;
        _pageInput.TextSubmitted += OnPageInputSubmitted;

        // 创建跳转按钮
        _goToButton.Text = "Go";
        _goToButton.Pressed += OnGoToButtonOnPressed;
    }

    private void OnFirstPageButtonOnPressed()
    {
        GoToPage(1);
    }

    private void OnGoToButtonOnPressed()
    {
        OnPageInputSubmitted(_pageInput.Text);
    }

    public void UnloadUI()
    {
        _firstPageButton.Pressed -= OnFirstPageButtonOnPressed;
        _prevButton.Pressed -= GoToPreviousPage;
        _nextButton.Pressed -= GoToNextPage;
        _lastPageButton.Pressed -= GoToLastPage;
        _pageInput.TextChanged -= OnPageInputTextChanged;
        _pageInput.TextSubmitted -= OnPageInputSubmitted;
        _goToButton.Pressed -= OnGoToButtonOnPressed;
    }

    public void SetTotalItems(int totalItems)
    {
        _totalItems = totalItems;
        _totalPages = Mathf.Max(1, Mathf.CeilToInt((float)_totalItems / ItemsPerPage));
        _currentPage = Mathf.Clamp(_currentPage, 1, _totalPages);

        UpdateUI();
    }

    public void GoToPage(int page)
    {
        int newPage = Mathf.Clamp(page, 1, _totalPages);
        _currentPage = newPage;
        UpdateUI();
        OnPageChanged?.Invoke(_currentPage);
    }

    private void GoToPreviousPage()
    {
        GoToPage(_currentPage - 1);
    }

    private void GoToNextPage()
    {
        GoToPage(_currentPage + 1);
    }

    private void GoToFirstPage()
    {
        GoToPage(1);
    }

    private void GoToLastPage()
    {
        GoToPage(_totalPages);
    }

    private void OnPageInputTextChanged(string newText)
    {
        // 验证输入是否为数字
        if (string.IsNullOrEmpty(newText) || newText == "0")
            return;

        if (!int.TryParse(newText, out int page) || page < 0)
        {
            // 移除非数字字符
            string cleanText = new string(newText.Where(char.IsDigit).ToArray());
            if (_pageInput.Text != cleanText)
            {
                _pageInput.Text = cleanText;
                _pageInput.CaretColumn = _pageInput.Text.Length;
            }
        }
    }

    private void OnPageInputSubmitted(string text)
    {
        if (int.TryParse(text, out int page))
        {
            GoToPage(page);
        }
    }

    private void UpdateUI()
    {
        _pageInfoLabel.Text = $"Page {_currentPage} of {_totalPages}";
        _pageInput.Text = _currentPage.ToString();

        // 更新按钮状态
        _prevButton.Disabled = _currentPage <= 1;
        _nextButton.Disabled = _currentPage >= _totalPages;
        _firstPageButton.Disabled = _currentPage <= 1;
        _lastPageButton.Disabled = _currentPage >= _totalPages;
    }

    public (int start, int end) GetPageRange()
    {
        var start = (_currentPage - 1) * ItemsPerPage;
        var end = Mathf.Min(start + ItemsPerPage, _totalItems);
        return (start, end);
    }
}